dw2elf: fix ELF alignment, add DW_DLC_SYMBOLIC_RELOCATIONS for DWARF#137
Conversation
ELF alignment fix:
The ELF spec requires p_offset ≡ p_vaddr (mod p_align). With
p_align=AOUT_INITRND=0x200000 the constraint was violated (text_foff=176
vs text_vaddr=0x200028, 176≠40 mod 0x200000), causing the kernel to
reject the binary and fall back to shell execution (the '(' in
"Syntax error: ( unexpected" is byte 0x28 = low byte of entry 0x200028).
Fix: use p_align=PAGE_SIZE=0x1000 and pad text/data file offsets so
text_foff ≡ text_vaddr and data_foff ≡ data_vaddr (mod PAGE_SIZE).
DWARF fix:
libdwarfp comment: "Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS".
Without it the library uses binary ELF stream relocations which silently
produce no sections for x86_64, so n_dw_sects stayed 0.
Also add error reporting when dwarf_producer_init fails.
https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs
There was a problem hiding this comment.
Code Review
This pull request updates dw2elf.c to ensure ELF file offsets align with virtual addresses modulo PAGE_SIZE, satisfying ELF alignment requirements. This is achieved by calculating necessary padding after headers and between sections and writing it to the output file. The dwarf_producer_init call was also updated to include symbolic relocations. Feedback suggests optimizing the padding implementation by using a single xwrite call with a zeroed buffer instead of writing byte-by-byte, and improving error reporting for DWARF initialization by including descriptive error messages from libdwarf.
| if(res != DW_DLV_OK) { | ||
| fprintf(stderr, "dw2elf: dwarf_producer_init failed\n"); | ||
| } else { |
There was a problem hiding this comment.
| /* ── text and data ── */ | ||
| /* ── padding + text + padding + data ── */ | ||
| cur = (long)(EHDR_SIZE + 2 * PHDR_SIZE); | ||
| while(cur < text_foff) { xwrite(ofd, &zero, 1); cur++; } |
There was a problem hiding this comment.
Writing padding byte-by-byte using xwrite is inefficient as it results in a system call for every single byte. Since the maximum padding is PAGE_SIZE, it's better to write the padding in a single call using a zeroed buffer.
if(cur < text_foff) {
static char zeros[PAGE_SIZE];
xwrite(ofd, zeros, text_foff - cur);
cur = text_foff;
}| while(cur < text_foff) { xwrite(ofd, &zero, 1); cur++; } | ||
| xwrite(ofd, aout_buf + AOUT_HEADR, textsize); | ||
| cur += (long)textsize; | ||
| while(cur < data_foff) { xwrite(ofd, &zero, 1); cur++; } |
There was a problem hiding this comment.
ELF alignment fix:
The ELF spec requires p_offset ≡ p_vaddr (mod p_align). With
p_align=AOUT_INITRND=0x200000 the constraint was violated (text_foff=176
vs text_vaddr=0x200028, 176≠40 mod 0x200000), causing the kernel to
reject the binary and fall back to shell execution (the '(' in
"Syntax error: ( unexpected" is byte 0x28 = low byte of entry 0x200028).
Fix: use p_align=PAGE_SIZE=0x1000 and pad text/data file offsets so
text_foff ≡ text_vaddr and data_foff ≡ data_vaddr (mod PAGE_SIZE).
DWARF fix:
libdwarfp comment: "Non-MIPS Non IA64 should use DW_DLC_SYMBOLIC_RELOCATIONS".
Without it the library uses binary ELF stream relocations which silently
produce no sections for x86_64, so n_dw_sects stayed 0.
Also add error reporting when dwarf_producer_init fails.
https://claude.ai/code/session_01WGAwvvTwDg2yknFkmZ3qzs